package com.tsd.jxc.stock.service.impl;

import com.tsd.base.service.BaseCodeRuleService;
import com.tsd.common.vo.BatchDeleteLogicVo;
import com.tsd.core.service.GetDuplicatedObj;
import com.tsd.core.thread.ThreadPoolTaskUtil;
import com.tsd.core.utils.HlpUtils;
import com.tsd.core.utils.ListUtil;
import com.tsd.core.vo.HlpException;
import com.tsd.core.vo.PageBean;
import com.tsd.jxc.config.JxcCodeRuleConstants;
import com.tsd.jxc.stock.StockConstants;
import com.tsd.jxc.stock.dao.JxcStockTransferItemMapper;
import com.tsd.jxc.stock.dao.JxcStockTransferMapper;
import com.tsd.jxc.stock.entity.*;
import com.tsd.jxc.stock.service.*;
import com.tsd.service.BaseServiceImpl;
import com.tsd.system.entity.SysUser;
import com.tsd.system.entity.SysUserExt;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 描述：JxcStockTransfer 服务实现层
 *
 * @author Hillpool
 * @date 2022/12/12 11:32:10
 */
@Service
public class JxcStockTransferServiceImpl extends BaseServiceImpl implements JxcStockTransferService, GetDuplicatedObj {

    @Resource
    private JxcStockTransferMapper jxcStockTransferMapper;
    @Resource
    private JxcStockTransferItemMapper jxcStockTransferItemMapper;
    @Resource
    private JxcStockTransferItemService jxcStockTransferItemService;
    @Resource
    private BaseCodeRuleService baseCodeRuleService;
    @Resource
    private JxcStockInbillService jxcStockInbillService;
    @Resource
    private JxcStockOutbillService jxcStockOutbillService;

    @Override
    public JxcStockTransfer getJxcStockTransferById(Long id) throws Exception {
        return jxcStockTransferMapper.selectByPrimaryKey(id);
    }

    @Override
    public JxcStockTransferExt queryBySid(String sid) throws Exception {
        JxcStockTransferExt transferExt = jxcStockTransferMapper.selectBySid(sid);
        if (transferExt != null) {
            List<JxcStockTransferItemExt> itemExtList = jxcStockTransferItemService.queryValidByTransferList(Collections.singletonList(sid));
            transferExt.setItem_list(itemExtList);
        }
        return transferExt;
    }

    @Override
    public void deleteJxcStockTransfers(List<String> list, SysUser opUser) throws Exception {
        if (HlpUtils.isEmptyList(list)) {
            return;
        }
        BatchDeleteLogicVo logicVo = new BatchDeleteLogicVo(opUser);
        logicVo.setSidList(list);
    }

    @Override
    public void saveJxcStockTransfer(JxcStockTransferExt record, SysUser opUser) throws Exception {
        if (HlpUtils.isEmpty(record.getId())) {
            if (!HlpUtils.isEmpty(record.getCode())) {
                //如果是手动设置了编号，则检查是否有相同的，有的话，置空后重新生成
                JxcStockTransferExt same = jxcStockTransferMapper.selectDuplicatedCode(record);
                if (same != null) {
                    record.setCode(null);
                }
            }
            if (HlpUtils.isEmpty(record.getCode())) {
                String genCode = baseCodeRuleService.genCode(null, JxcCodeRuleConstants.TYPE_JXC_STOCK_TRANSFER, JxcCodeRuleConstants.TYPE_NAME_JXC_STOCK_TRANSFER, opUser, record.getCode(), record, this);
                record.setCode(genCode);
            }
            super.autoInjectBaseData(record, opUser, this.TYPE_CREATE);
            jxcStockTransferMapper.insertSelective(record);
        } else {
            //如果是手动设置了编号，则检查是否有相同的，有的话，置空后重新生成
            JxcStockTransferExt same = jxcStockTransferMapper.selectDuplicatedCode(record);
            if (same != null) {
                throw new HlpException("已存在相同编号的记录");
            }
            super.autoInjectBaseData(record, opUser, this.TYPE_UPDATE);
            jxcStockTransferMapper.updateByPrimaryKeySelective(record);
        }
        jxcStockTransferItemService.saveJxcStockTransferItem(record, opUser);
    }

    @Override
    public List<JxcStockTransferExt> findJxcStockTransfers(Map<String, Object> params, PageBean page) throws Exception {
        if (params.containsKey("goods_name")) {
            String goods_name = HlpUtils.getString(params, "goods_name");
            List<JxcStockTransferItemExt> list = jxcStockTransferItemMapper.selectByGoodsName(goods_name);
            if (list == null || list.isEmpty()) {
                return null;
            }
            List<String> transferSids = ListUtil.map(list, JxcStockTransferItemExt::getTransfer_sid).stream().distinct().collect(Collectors.toList());
            params.put("transferSids", transferSids);
        }
        return jxcStockTransferMapper.selectByPage(params, page);
    }

    @Override
    public List<JxcStockTransferExt> findJxcStockTransfers(Map<String, Object> params) throws Exception {
        return jxcStockTransferMapper.selectByParams(params);
    }

    @Override
    public void changeJxcStockTransferAuditState(List<String> sidList, Integer state, SysUserExt opUser) throws HlpException {
        JxcStockTransferExt params = new JxcStockTransferExt();
        params.setDr(0);
        params.setSid_list(sidList);
        List<JxcStockTransferExt> transferExtList = jxcStockTransferMapper.selectByEntity(params);
        if (HlpUtils.isEmptyList(transferExtList)) {
            return;
        }
        List<String> transferSids = ListUtil.map(transferExtList, JxcStockTransferExt::getSid);
        List<JxcStockTransferItemExt> itemExtList = jxcStockTransferItemMapper.selectBySids(transferSids, 0);
        if (itemExtList == null || itemExtList.isEmpty()) {
            return;
        }
        for (JxcStockTransferExt transferExt : transferExtList) {
            if (state == 1) {
                transferExt.setAudit_state(StockConstants.STATE_AUDITED);
                transferExt.setAuditor_sid(opUser.getSid());
                transferExt.setAuditor_name(opUser.getName());
                transferExt.setAudit_date(new Date());
            } else if (state == -1) {
                transferExt.setAudit_state(StockConstants.STATE_UN_AUDIT);
                transferExt.setAuditor_sid(null);
                transferExt.setAuditor_name(null);
                transferExt.setAudit_date(null);
            }
            super.autoInjectBaseData(transferExt, opUser, this.TYPE_UPDATE);
        }

        ThreadPoolTaskUtil.executeInList4Split(transferExtList, false, list -> {
            jxcStockTransferMapper.updateList(list);
        });
    }

    @Override
    public void genJxcStockTransfers2InAndOutBill(List<String> sidList, SysUserExt opUser) throws Exception {
        List<JxcStockTransferExt> stockTransferExtList = this.queryBySidList(sidList);
        stockTransferExtList = ListUtil.filter(stockTransferExtList, t -> !StockConstants.DETAIL_IN_OUT_BILL_ALL.equals(t.getGen_in_out_bill()));
        if (HlpUtils.isEmptyList(stockTransferExtList)) {
            return;
        }
        List<JxcStockTransferExt> updateList = new ArrayList<>();
        List<JxcStockTransferItemExt> updateDetailList = new ArrayList<>();
        for (JxcStockTransferExt transferExt : stockTransferExtList) {
            JxcStockInbillExt inBillExt = transferExt.genInBill(null);
            JxcStockOutbillExt outBillExt = transferExt.genOutBill(null);
            if (HlpUtils.isEmptyList(inBillExt.getItem_list())) {
                continue;
            }
            jxcStockInbillService.saveJxcStockInbill(inBillExt, opUser);
            jxcStockOutbillService.saveJxcStockOutbill(outBillExt, opUser);
            transferExt.setGen_in_out_bill(StockConstants.DETAIL_IN_OUT_BILL_ALL);
            super.autoInjectBaseData(transferExt, opUser, this.TYPE_UPDATE);
            updateList.add(transferExt);
            for (JxcStockTransferItemExt itemExt : transferExt.getItem_list()) {
                super.autoInjectBaseData(itemExt, opUser, this.TYPE_UPDATE);
                updateDetailList.add(itemExt);
            }
        }
        if (!HlpUtils.isEmptyList(updateList)) {
            ThreadPoolTaskUtil.executeInList4Split(updateList, false, itemList -> jxcStockTransferMapper.updateList(itemList));
        }
        if (!HlpUtils.isEmptyList(updateDetailList)) {
            ThreadPoolTaskUtil.executeInList4Split(updateDetailList, false, itemList -> jxcStockTransferItemMapper.updateList(itemList));
        }
    }

    @Override
    public List<JxcStockTransferExt> findJxcStockTransfersIncludeDetail(Map<String, Object> params, PageBean page) {
        return jxcStockTransferMapper.selectStockTransfersIncludeDetailByPage(params, page);
    }

    private List<JxcStockTransferExt> queryBySidList(List<String> sidList) {
        List<JxcStockTransferExt> stockTransferExtList = ThreadPoolTaskUtil.queryInList4Split(sidList, list -> {
            JxcStockTransferExt params = new JxcStockTransferExt();
            params.setDr(0);
            params.setSid_list(list);
            return jxcStockTransferMapper.selectByEntity(params);
        });
        if (HlpUtils.isEmptyList(stockTransferExtList)) {
            return null;
        }
        List<String> orderList = ListUtil.map(stockTransferExtList, JxcStockTransferExt::getSid);

        List<JxcStockTransferItemExt> detailExtList = ThreadPoolTaskUtil.queryInList4Split(orderList, list -> jxcStockTransferItemService.queryValidByOrderList(list));
        if (HlpUtils.isEmptyList(detailExtList)) {
            return null;
        }
        for (JxcStockTransferExt transferExt : stockTransferExtList) {
            List<JxcStockTransferItemExt> filterList = ListUtil.filter(detailExtList, t -> t.getTransfer_sid().equals(transferExt.getSid()));
            if (HlpUtils.isEmptyList(filterList)) {
                continue;
            }
            transferExt.setItem_list(filterList);
        }
        return ListUtil.filter(stockTransferExtList, t -> !HlpUtils.isEmptyList(t.getItem_list()));
    }

    @Override
    public boolean isDuplicated(Object obj, String code) {
        if (obj == null) {
            return false;
        }
        JxcStockTransferExt transferExt = (JxcStockTransferExt) obj;
        transferExt.setCode(code);
        return jxcStockTransferMapper.selectDuplicatedCode(transferExt) != null;
    }
}
